/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.sais.eswn.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Romulus
 */
public class DeliverWatchServer extends Sock {

    private ServerSocket mServerSocket;
    /**
     * The socket to recieve data from the host's HostSock.
     */
    private ServerSocket mToHostServerSocket;
    private Socket mToHostSocket;
    /**
     * The socket to data to watchers' ClientSock.
     */
    private ArrayList<ToWatcherSock> mToWatcherSocket = new ArrayList<ToWatcherSock>();
    private boolean mAccept = true;

    public DeliverWatchServer(int listenport, int hostport) {
        try {
            mServerSocket = new ServerSocket(listenport);
            mToHostServerSocket = new ServerSocket(hostport);
            showDialog = false;
        } catch (IOException ex) {
            Logger.getLogger(DeliverWatchServer.class.getName()).log(Level.SEVERE, null, ex);
            return;
        }
        start();
        new WatcherAccepter().start();
    }

    @Override
    public void scan() {
    }

    class WatcherAccepter extends Thread {

        @Override
        public void run() {
            try {
                while (mAccept) {
                    Socket incomingSoc;
                    incomingSoc = mServerSocket.accept();
                    ToWatcherSock newWatcher = new ToWatcherSock(incomingSoc);
                    mToWatcherSocket.add(newWatcher);
                    send(incomingSoc, "$YOUAREWATCHER:");
                    newWatcher.start();
                }
            } catch (IOException ex) {
                Logger.getLogger(DeliverWatchServer.class.getName()).log(Level.SEVERE, null, ex);
                return;
            }
        }
    }

    class ToWatcherSock extends Sock {

        public ToWatcherSock(Socket soc) {
            this.mSocket = soc;
        }

        @Override
        public void closeSocket() {
            try {
                mSocket.close();
            } catch (IOException ex) {
                Logger.getLogger(DeliverWatchServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        @Override
        public void run() {
            scan();
        }

        @Override
        public void scan() {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(mSocket.getInputStream(), "Unicode"));
                String instr;
                while ((instr = in.readLine()) != null) {
                    instr = Fix(instr);
                    if (debug) {
                        Calendar c = Calendar.getInstance();
                        System.out.println("TOWATSOC " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND) + "/ " + instr);
                    }
                    send(mToHostSocket, instr);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }

        }
    }

    @Override
    public void run() {
        try {
            mToHostSocket = mToHostServerSocket.accept();
            BufferedReader in = new BufferedReader(new InputStreamReader(mToHostSocket.getInputStream(), "Unicode"));
            String instr;
            while ((instr = in.readLine()) != null) {
                instr = Fix(instr);
                if (debug) {
                    Calendar c = Calendar.getInstance();
                    System.out.println("DELIVER " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND) + "/ " + instr);
                }
                for (ToWatcherSock s : mToWatcherSocket) {
                    send(s.getSocket(), instr);
                }
            }
        } catch (SocketException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    public void stopAccept() {
        mAccept = false;
    }

    @Override
    public void closeSocket() {
        try {
            mAccept = false;
            for (ToWatcherSock s : mToWatcherSocket) {
                s.closeSocket();
            }
            mToHostSocket.close();
        } catch (IOException ex) {
            Logger.getLogger(DeliverWatchServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
